package scigest.core;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.perf4j.aop.Profiled;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;



/**
 * This class implements a "simple" dataset mapping strategy
 * where we assume no encoding info on directory name
 * 
 * Some assumptions are made about layout and parsing:
 * 
 * <ul>
 *   <li> If you have nc files on dataset root, we will assume this is a flat structure, where
 *        no further parsing is done </li>
 *        
 *   <li> If you don't have nc files on root, but directories, then this is nested structure. </li>
 *   
 *   
 *   <li> The default depth for composing parent is 2, but this should be configurable </li>
 *   
 * </ul>
 * 
 * @author Feiyi Wang
 *
 */

@Component
public class SimpleDatasetMapping implements DatasetMapping {
	
	private static final Logger logger = LoggerFactory.getLogger(SimpleDatasetMapping.class);
	private int depth = 1;
	private Collection<File> fc;
	
	SimpleDatasetMapping() {
	}
	
	SimpleDatasetMapping(int depth) {
		this.depth = depth;
	}
	
	@Override
	@Profiled(tag="scanDirectory")
	public Map<File, ArrayList<File>> getFileMap(File startDir) {
		
		Map<File, ArrayList<File>> res = new HashMap<File, ArrayList<File>>();
		
		fc = FileUtils.listFiles(startDir, new String[] {"nc", "cdf"}, false);
		
		if (! fc.isEmpty()) {			
			logger.debug("Detect nc files at the root, assume flat directory structure");
			res.put(startDir, new ArrayList<File>(fc));
			return res;
		}

		// nested directory		
		String[] dirList = startDir.list( DirectoryFileFilter.INSTANCE );
				
		if (dirList.length == 0) {
			logger.debug("No sub-directories detected, this is odd, return empty map!");
			return res;
		}
		
		
		scanSubDirectory(startDir, res, dirList);
		
		return res;
	}

	
	public void scanSubDirectory(File startDir,
			Map<File, ArrayList<File>> res, String[] dirList) {
		// for each sub-directory, we walk		
		for (String dir: dirList) {
			
			logger.debug("Scanning {}", dir);

			File subDir = new File(startDir.getPath(), dir);
			fc = FileUtils.listFiles(subDir, new String[] {"nc", "cdf"}, true);			
			res.put(subDir, new ArrayList<File>(fc));
			
			
		}
	}

	/**
	 * Dump contents of a file map, only for debugging purpose
	 * @throws IOException 
	 */
	public static void dumpFileMap(Map<File, ArrayList<File>> m) throws IOException {
		for (File f: m.keySet()) {
			System.out.printf("%s\n", f.getCanonicalPath());
			ArrayList<File> flist = m.get(f);
			for (File fitem: flist) {
				System.out.printf("\t --> %s\n", fitem.getCanonicalPath());
			}
		}
	}
	
	public static void main(String[] args) throws IOException {
		File dir = new File("/Users/fwang2/scigest/samples/clm_flat");
		SimpleDatasetMapping smp = new SimpleDatasetMapping();
		
		dumpFileMap(smp.getFileMap(dir));
		
		
	}
	
}
